package google.apps.reporting;


import google.apps.reporting.utils.ReportUploaderUtil;
import google.apps.reporting.utils.WorkBookGenerator;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;

import java.text.DateFormat;
import java.text.SimpleDateFormat;

import java.util.Arrays;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Vector;

import javax.print.attribute.AttributeSet;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JEditorPane;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.filechooser.FileFilter;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.JTableHeader;
import javax.swing.text.BadLocationException;


/**
 *
 * ReportFrame class is the main window of the UI. Its a Swing JFrame.
 */
public class ReportFrame extends JFrame {
  private JLabel lblDomainName = new JLabel();
  private JTextField txtDomainName = new JTextField();
  private JLabel lblReportName = new JLabel();
  private JLabel lblReportDate = new JLabel();
  private JButton btnSubmit = new JButton();
  private JLabel lblUserName = new JLabel();
  private JLabel lblPassword = new JLabel();
  private JPasswordField txtPassword = new JPasswordField();
  private JTextField txtUserName = new JTextField();
  private JTable tblReportData = new JTable();
  private JScrollPane spTableData = new JScrollPane();
  private JComboBox cbReportNames =
    new JComboBox(new Object[] { "accounts", "summary", "activity",
                                 "email_clients", "quota_limit_accounts",
                                 "disk_space", "suspended_accounts" });
  private JCheckBox chkTextFile = new JCheckBox();
  private JCheckBox chkExcel = new JCheckBox();
  private JCheckBox chkGoogleDocs = new JCheckBox();
  private JCheckBox chkScreen = new JCheckBox();
  private JFileChooser fileChooser = new JFileChooser();
  private JPanel panelViewOptions = new JPanel();

  private FlowLayout flowLayout1 = new FlowLayout();
  private JComboBox cbDay = new JComboBox();
  private JComboBox cbMonth =
    new JComboBox(new Object[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
                                 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" });
  private JComboBox cbYear = new JComboBox();

  private static final DateFormat DATE_TIME_FORMAT =
    new SimpleDateFormat("yyyy-MM-dd");
  private JCheckBox jCheckBox1 = new JCheckBox();
  private JTextField jTextField1 = new JTextField();
  private JLabel jLabel1 = new JLabel();


  public ReportFrame() {
    try {
      jbInit();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * Draws all components on the main frame.
   * @throws Exception
   */
  private void jbInit() throws Exception {
    this.getContentPane().setLayout(null);
    this.setSize(new Dimension(1024, 768));
    this.setTitle("Google Apps Reports");
    lblDomainName.setText("Domain");
    lblDomainName.setBounds(new Rectangle(430, 20, 120, 30));
    lblDomainName.setSize(new Dimension(120, 30));
    txtDomainName.setBounds(new Rectangle(500, 20, 120, 30));
    txtDomainName.setSize(new Dimension(120, 30));
    lblReportName.setText("Report");
    lblReportName.setBounds(new Rectangle(25, 55, 120, 30));
    lblReportName.setSize(new Dimension(120, 30));
    lblReportDate.setText("Date");
    lblReportDate.setBounds(new Rectangle(225, 55, 120, 30));
    lblReportDate.setSize(new Dimension(120, 30));
    btnSubmit.setText("Get Report");
    btnSubmit.setBounds(new Rectangle(495, 55, 125, 30));
    btnSubmit.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            btnSubmit_actionPerformed(e);
          }
        });
    lblUserName.setText("Username");
    lblUserName.setBounds(new Rectangle(25, 20, 120, 30));
    lblUserName.setSize(new Dimension(120, 30));
    lblPassword.setText("Password");
    lblPassword.setBounds(new Rectangle(225, 20, 120, 30));
    lblPassword.setSize(new Dimension(120, 30));
    txtPassword.setNextFocusableComponent(txtDomainName);
    txtPassword.setBounds(new Rectangle(300, 20, 120, 30));
    txtPassword.setSize(new Dimension(120, 30));
    txtUserName.setNextFocusableComponent(txtPassword);
    txtUserName.setBounds(new Rectangle(95, 20, 120, 30));

    txtUserName.setSize(new Dimension(120, 30));
    cbReportNames.setBounds(140, 130, 95, 30);
    panelViewOptions.add(chkScreen, BorderLayout.WEST);
    panelViewOptions.add(chkExcel, BorderLayout.CENTER);
    panelViewOptions.add(chkTextFile, BorderLayout.CENTER);
    panelViewOptions.add(chkGoogleDocs, BorderLayout.EAST);
    this.getContentPane().add(jLabel1, null);
    this.getContentPane().add(jTextField1, null);
    this.getContentPane().add(cbYear, null);
    this.getContentPane().add(cbMonth, null);
    this.getContentPane().add(panelViewOptions, null);
    spTableData.getViewport().add(tblReportData, null);
    this.getContentPane().add(spTableData, null);
    this.getContentPane().add(btnSubmit, null);
    this.getContentPane().add(lblReportName, null);
    lblReportDate.add(cbDay, null);
    this.getContentPane().add(lblReportDate, null);
    this.getContentPane().add(txtDomainName, null);
    this.getContentPane().add(lblPassword, null);
    this.getContentPane().add(txtPassword, null);
    this.getContentPane().add(txtUserName, null);
    this.getContentPane().add(lblUserName, null);
    this.getContentPane().add(lblDomainName, null);
    this.getContentPane().add(cbReportNames, null);
    tblReportData.setShowGrid(true);
    tblReportData.setTableHeader(new JTableHeader());
    tblReportData.setColumnModel(new DefaultTableColumnModel());
    spTableData.setBounds(new Rectangle(15, 140, 980, 560));
    cbReportNames.setBounds(new Rectangle(95, 60, 120, 30));
    cbReportNames.setSize(new Dimension(120, 30));
    chkTextFile.setText("Text File");
    chkExcel.setText("Excel");
    chkGoogleDocs.setText("Google Docs");
    chkScreen.setText("Onscreen");

    panelViewOptions.setBounds(new Rectangle(635, 15, 360, 70));
    panelViewOptions.setLayout(flowLayout1);
    panelViewOptions.setBorder(BorderFactory.createTitledBorder("View Report Options"));
    cbDay.setBounds(new Rectangle(45, 5, 70, 25));
    for (int i = 1; i <= 31; i++) {
      cbDay.addItem(i);
    }
    cbMonth.setBounds(new Rectangle(335, 60, 70, 25));
    cbYear.setBounds(new Rectangle(400, 60, 85, 25));


    jCheckBox1.setText("jCheckBox1");
    jTextField1.setBounds(new Rectangle(95, 95, 895, 30));
    Calendar instance = GregorianCalendar.getInstance();
    int year = instance.get(Calendar.YEAR);


    for (int i = 0; i <= 10; i++) {
      cbYear.addItem(year--);
    }

    cbDay.setSelectedIndex(instance.get(Calendar.DAY_OF_MONTH));
    cbMonth.setSelectedIndex(instance.get(Calendar.MONTH));
    jTextField1.setBackground(this.getBackground());
    jLabel1.setText("Docs URL");
    jLabel1.setBounds(new Rectangle(25, 100, 60, 20));
    this.setResizable(false);

  }

  /**
   * Event handler for Submit action.
   * 1. Fetch report
   * 2. Create WorkBook
   * 3. Upload to admin's Google Docs account
   * @param e
   */
  private void btnSubmit_actionPerformed(ActionEvent e) {
    ReportRunner runner = new ReportRunner();
    String adminUsername = txtUserName.getText().trim();
    String domain = txtDomainName.getText().trim();
    String adminEmail = adminUsername + "@" + domain;
    String storageDir = null;
    String password = txtPassword.getText();
    String workBookPath = null;
    String uploadedUrl = null;
    String date = "";
    Calendar cal =
      new GregorianCalendar(Integer.parseInt(cbYear.getSelectedItem().toString()),
                            cbMonth.getSelectedIndex(),
                            Integer.parseInt(cbDay.getSelectedItem().toString()));
    date = DATE_TIME_FORMAT.format(cal.getTime());
    System.out.println(date);
    runner.setAdminEmail(adminEmail);
    runner.setAdminPassword(password);
    runner.setDomain(domain);
    File reportFile = null;
    FileOutputStream out = null;
    FileReader inFileReader = null;
    BufferedReader bufReader = null;
    String docsPath =null;
    String tempFile = "";
    try {
      reportFile = File.createTempFile("report_" + System.nanoTime(), ".txt");
      tempFile = reportFile.getAbsolutePath();
      System.out.println(tempFile);
      out = new FileOutputStream(reportFile);

      runner.runReport(cbReportNames.getSelectedItem().toString(), date, out);
      out = null;

      reportFile = new File(tempFile);
      inFileReader = new FileReader(reportFile);
      bufReader = new BufferedReader(inFileReader);

      if (chkExcel.isSelected() || chkGoogleDocs.isSelected()) {
        if (chkExcel.isSelected()) {


          fileChooser.setDialogType(JFileChooser.CUSTOM_DIALOG);
          fileChooser.setDialogTitle("Save Excel - Choose Directory ");
          fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
          fileChooser.addChoosableFileFilter(new FileFilter() {
                public boolean accept(File f) {
                  return f.isDirectory() && f.canWrite();
                }

                public String getDescription() {
                  return "Choose Directory";
                }
              });
          switch (fileChooser.showDialog(this, "Select")) {
          case JFileChooser.CANCEL_OPTION:
            break;
          case JFileChooser.APPROVE_OPTION:
            storageDir = fileChooser.getCurrentDirectory().getAbsolutePath();
            break;
          default:

          }


        }
        workBookPath = WorkBookGenerator.generateWorkBookFromCSVData(bufReader, storageDir);
        if (chkGoogleDocs.isSelected()) {
          uploadedUrl = ReportUploaderUtil.uploadWorkbook(adminEmail, password, workBookPath);
        }
        
        jTextField1.setText(uploadedUrl);
        jTextField1.setEditable(false);
      }

      bufReader.close();
      inFileReader.close();
      //inFileReader.reset();
      if (chkTextFile.isSelected()) {

      }
      //TODO: optimize the file reading process
      inFileReader = new FileReader(reportFile);
      bufReader = new BufferedReader(inFileReader);


      String[] columns = bufReader.readLine().split(",");
      Vector<String> columnNames = new Vector<String>(columns.length);
      columnNames.addAll(Arrays.asList(columns));

      String eachRow = null;
      Vector<Vector> allRows = new Vector<Vector>();
      Vector<String> eachRowData = new Vector<String>(columns.length);

      while ((eachRow = bufReader.readLine()) != null) {
        eachRowData = new Vector<String>(columns.length);
        eachRowData.addAll(Arrays.asList(eachRow.split(",")));
        allRows.add(eachRowData);
      }
      
      if (chkTextFile.isSelected()) {
            reportFile.renameTo(new File ("/Users/anirudhd/Reports/temp.txt"));
      }

       tblReportData = new JTable(allRows, columnNames);
      tblReportData.setAutoscrolls(true);
      spTableData.setAutoscrolls(true);
      spTableData.getViewport().add(tblReportData);


    } catch (FileNotFoundException f) {
      f.printStackTrace();
    } catch (IOException f) {
      f.printStackTrace();
    } catch (ReportException f) {
      f.printStackTrace();
    } finally {
      try {
        
        bufReader.close();
        inFileReader.close();
        
      } catch (Exception ex) {
        ex.printStackTrace();
      }
    }

  }


}
